<template>
  <view class="warp">
    <view class="cate">
      <text class="text">分类</text>
      <u-radio-group v-model="article.categoryName" @change="radioGroupChange" size="46">
        <u-radio v-for="(item, index) in categories" :key="index" :name="item.name">{{ item.name }}</u-radio>
      </u-radio-group>
    </view>
    <view class="cate">
      <text class="text">标题</text>
      <input type="text" class="input" v-model="article.post_title" placeholder="请输入标题" maxlength="100" />
    </view>
    <view class="prase">
      <!-- 富文本编辑器 文档：https://uniapp.dcloud.io/component/editor?id=editor -->
      <view class="toolbar" @click="format" v-if="!readOnly">
        <view :class="formats.bold ? 'ql-active' : ''" class="iconfont icon-zitijiacu" data-name="bold"></view>
        <view :class="formats.italic ? 'ql-active' : ''" class="iconfont icon-zitixieti" data-name="italic"></view>
        <view :class="formats.underline ? 'ql-active' : ''" class="iconfont icon-zitixiahuaxian" data-name="underline"></view>
        <view :class="formats.strike ? 'ql-active' : ''" class="iconfont icon-zitishanchuxian" data-name="strike"></view>
        <view :class="formats.align === 'left' ? 'ql-active' : ''" class="iconfont icon-zuoduiqi" data-name="align" data-value="left"></view>
        <view :class="formats.align === 'center' ? 'ql-active' : ''" class="iconfont icon-juzhongduiqi" data-name="align" data-value="center"></view>
        <view :class="formats.align === 'right' ? 'ql-active' : ''" class="iconfont icon-youduiqi" data-name="align" data-value="right"></view>
        <view :class="formats.align === 'justify' ? 'ql-active' : ''" class="iconfont icon-zuoyouduiqi" data-name="align" data-value="justify"></view>
        <view :class="formats.lineHeight ? 'ql-active' : ''" class="iconfont icon-line-height" data-name="lineHeight" data-value="2"></view>
        <view :class="formats.letterSpacing ? 'ql-active' : ''" class="iconfont icon-Character-Spacing" data-name="letterSpacing" data-value="2em"></view>
        <view :class="formats.marginTop ? 'ql-active' : ''" class="iconfont icon-722bianjiqi_duanqianju" data-name="marginTop" data-value="20px"></view>
        <view :class="formats.previewarginBottom ? 'ql-active' : ''" class="iconfont icon-723bianjiqi_duanhouju" data-name="marginBottom" data-value="20px"></view>
        <view class="iconfont icon-clearedformat" @tap="editorCtx.removeFormat()"></view>
        <view :class="formats.fontFamily ? 'ql-active' : ''" class="iconfont icon-font" data-name="fontFamily" data-value="Pacifico"></view>
        <view :class="formats.fontSize === '24px' ? 'ql-active' : ''" class="iconfont icon-fontsize" data-name="fontSize" data-value="24px"></view>
        <view :class="formats.color === '#ff4400' ? 'ql-active' : ''" class="iconfont icon-text_color" data-name="color" data-value="#ff4400"></view>
        <view :class="formats.backgroundColor === '#00ffff' ? 'ql-active' : ''" class="iconfont icon-fontbgcolor" data-name="backgroundColor" data-value="#00ffff"></view>
        <view class="iconfont icon-date" @tap="insertDate"></view>
        <view class="iconfont icon--checklist" data-name="list" data-value="check"></view>
        <view :class="formats.list === 'ordered' ? 'ql-active' : ''" class="iconfont icon-youxupailie" data-name="list" data-value="ordered"></view>
        <view :class="formats.list === 'bullet' ? 'ql-active' : ''" class="iconfont icon-wuxupailie" data-name="list" data-value="bullet"></view>
        <view class="iconfont icon-undo" @tap="editorCtx.undo()"></view>
        <view class="iconfont icon-redo" @tap="editorCtx.redo()"></view>
        <view class="iconfont icon-outdent" data-name="indent" data-value="-1"></view>
        <view class="iconfont icon-indent" data-name="indent" data-value="+1"></view>
        <view class="iconfont icon-fengexian" @tap="editorCtx.insertDivider()"></view>
        <view class="iconfont icon-charutupian" @tap="uploadImage('editor')"></view>
        <view :class="formats.header === 1 ? 'ql-active' : ''" class="iconfont icon-format-header-1" data-name="header" :data-value="1"></view>
        <view :class="formats.script === 'sub' ? 'ql-active' : ''" class="iconfont icon-zitixiabiao" data-name="script" data-value="sub"></view>
        <view :class="formats.script === 'super' ? 'ql-active' : ''" class="iconfont icon-zitishangbiao" data-name="script" data-value="super"></view>
        <view class="iconfont icon-shanchu" @tap="editorCtx.clear()"></view>
        <view :class="formats.direction === 'rtl' ? 'ql-active' : ''" class="iconfont icon-direction-rtl" data-name="direction" data-value="rtl"></view>
      </view>
      <editor
        id="editor"
        class="ql-container"
        placeholder="在这里输入文章内容...(插入的第一张图片会作为文章缩略图)"
        showImgSize
        showImgToolbar
        showImgResizeonEditorReady
        @statuschange="onStatusChange"
        :read-only="readOnly"
        @ready="onEditorReady"
      ></editor>
    </view>
    <view class="btn">
      <u-button @click="submit">{{ id ? '保存' : '提交' }}</u-button>
    </view>
    <u-toast ref="uToast" />
  </view>
</template>

<script>
export default {
  data() {
    return {
      id: null,
      formats: {},
      readOnly: false,
      editorCtx: {},
      article: {},
      categories: []
    };
  },
  onLoad(options) {
    this.id = options.id;
    if (this.id) {
      uni.setNavigationBarTitle({
        title: '编辑文章'
      });
    } else {
      uni.setNavigationBarTitle({
        title: '添加文章'
      });
    }
    this.getCategories();
  },
  methods: {
    submit() {
      if (!this.article.categories) {
        this.$refs.uToast.show({
          title: '请选择文章分类',
          type: 'error'
        });
        return;
      }
      if (!this.article.post_title) {
        this.$refs.uToast.show({
          title: '请输入文章标题',
          type: 'error'
        });
        return;
      }
      if (this.article.post_title.length < 5) {
        this.$refs.uToast.show({
          title: '标题不能少于5个字',
          type: 'error'
        });
        return;
      }
      this.editorCtx.getContents({
        success: res => {
          this.article.post_content = res.html;
        }
      });
      if (this.article.post_content == '<p><br></p>') {
        this.$refs.uToast.show({
          title: '请输入文章内容',
          type: 'error'
        });
        return;
      }
      this.article.thumbnail = this.getFirstImg(this.article.post_content); // 获取文章第一张图片作为缩略图
      let url = 'portal/articles/save'; // 新增
      let data = {
        categories: this.article.categories,
        post_title: this.article.post_title,
        post_content: this.article.post_content,
        thumbnail: this.article.thumbnail
      };
      if (this.id) {
        url = 'portal/articles/update'; // 编辑
        data = {
          ...data,
          id: this.id
        };
      }
      this.$loading();
      this.$api.post({
        url: url,
        data: data,
        success: res => {
          if (res.code == 1) {
            this.$refs.uToast.show({
              title: res.msg,
              type: 'success',
              callback: () => {
                this.$u.route({
                  type: 'back'
                });
              }
            });
          } else {
            this.$refs.uToast.show({
              title: res.msg,
              type: 'error'
            });
          }
        },
        complete: () => {
          uni.hideLoading();
        }
      });
    },
    // 获取文章
    getArticle() {
      this.$api.get({
        url: `portal/articles/${this.id}`,
        success: res => {
          if (res.code == 1) {
            this.article = res.data;
            let categories = this.article.categories
            this.article.categories = categories[0].id;
            this.article.categoryName = categories[0].name;
            this.editorCtx.setContents({
              html: res.data.post_content
            });
          } else {
            this.$refs.uToast.show({
              title: res.msg,
              type: 'error'
            });
          }
        }
      });
    },
    // 获取分类
    getCategories() {
      this.$api.get({
        url: 'portal/categories',
        data: {
          order: '+id',
          field: 'id,name'
        },
        success: res => {
          if (res.code == 1) {
            this.categories = res.data.list;
          }
        }
      });
    },
    // 选中任一radio时，由radio-group触发
    radioGroupChange(e) {
      this.categories.forEach(item => {
        if (item.name === e) {
          this.article.categories = item.id;
          this.article.categoryName = item.name;
        }
      });
    },
    // 上传图片
    uploadImage() {
      let that = this;
      uni.chooseImage({
        count: 1,
        success: images => {
          that.$loading();
          that.$api.uploadFile({
            url: 'user/upload/one',
            filePath: images.tempFilePaths[0],
            name: 'file',
            success: resFile => {
              if (resFile.code == 1) {
                that.editorCtx.insertImage({
                  src: resFile.data.url
                });
              } else {
                that.$refs.uToast.show({
                  title: res.msg,
                  type: 'error'
                });
              }
            },
            complete: () => {
              uni.hideLoading();
            }
          });
        }
      });
    },
    // 初始化编辑器
    onEditorReady() {
      uni
        .createSelectorQuery()
        .select('#editor')
        .context(res => {
          this.editorCtx = res.context;
          if (this.id) {
            this.getArticle();
          }
        })
        .exec();
    },
    format(e) {
      let { name, value } = e.target.dataset;
      if (!name) return;
      this.editorCtx.format(name, value);
    },
    onStatusChange(e) {
      this.formats = e.detail;
    },
    insertDate() {
      const date = new Date();
      const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
      this.editorCtx.insertText({
        text: formatDate
      });
    },
    // 获取第一张图片作为缩略图
    getFirstImg(html) {
      let src = '';
      html.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/, (match, capture) => {
        src = capture;
      });
      return src;
    }
  }
};
</script>

<style lang="scss" scoped>
@import '@/static/css/editor-icon.css';
.prase {
  background: #ffffff;
  .iconfont {
    display: inline-block;
    padding: 8px 8px;
    width: 24px;
    height: 24px;
    cursor: pointer;
    font-size: 20px;
  }
  .toolbar {
    display: flex;
    flex-wrap: wrap;
    padding-left: 10rpx;
    view {
      margin: 0 10rpx 10rpx;
    }
  }
  .ql-container {
    box-sizing: border-box;
    padding: 10px;
    width: 100%;
    min-height: 20vh;
    height: auto;
    font-size: 16px;
    line-height: 1.5;
    margin-top: 20rpx;
  }
  .ql-active {
    color: #06c;
  }
}
.cate {
  display: flex;
  align-items: center;
  padding: 30rpx 40rpx;
  background: #fff;
  margin-bottom: 20rpx;
  .text {
    font-size: 30rpx;
    font-weight: bold;
    margin-right: 20rpx;
    width: 80rpx;
  }
  .input {
    font-size: 32rpx;
    width: 100%;
  }
}
.btn {
  margin: 50rpx;
}
</style>
